package com.fingard.dsp.bank.directbank.bozz02;

import java.math.BigDecimal;
import java.util.Date;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directbank.PaymentState;
import com.fingard.dsp.bank.directbank.bankInterface.ISinglePay;
import com.fingard.dsp.bank.reqrespobj.single.ReqQrySingle;
import com.fingard.dsp.bank.reqrespobj.single.ReqQrySingleBat;
import com.fingard.dsp.bank.reqrespobj.single.ReqSingle;
import com.fingard.dsp.bank.reqrespobj.single.ReqSingleBat;
import com.fingard.dsp.bank.reqrespobj.single.RetAtsSingle;
import com.fingard.dsp.bank.reqrespobj.single.RetAtsSingleBat;
import com.fingard.dsp.bank.reqrespobj.single.detail.RetAtsSglDetail;
import com.fingard.net.ConnState;
import com.fingard.text.StringHelper;
import com.fingard.xml.XElement;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

/**
 * 郑州银行单笔支付
 * 
 * @author Cruise
 * @date 2018/11/28
 */
public class BOZZ02SinglePay extends BOZZ02Base implements ISinglePay {
    @Override
    public RetAtsSingle d_1908_SglPay(ReqSingle p_req1908) throws Exception {
        if ("1".equals(p_req1908.singleDetail.sameBnk)) {
            return innerPay(p_req1908);
        } else {
            return crossPay(p_req1908);
        }
    }
    
    /**
     * 同行单笔支付
     * 
     * @param pReq1908
     * @return
     * @throws Exception
     */
    public RetAtsSingle innerPay(ReqSingle pReq1908) throws Exception {
        RetAtsSingle retAts = new RetAtsSingle(pReq1908.reqHeader);
        RetAtsSglDetail tmpRetDetail = new RetAtsSglDetail();
        tmpRetDetail.reqSeqID = pReq1908.singleDetail.askNumber;
        
        try {
        	BOZZ02Header tmpBankHeader = new BOZZ02Header();
            tmpBankHeader.trsCode = "B2EBankInnerTransfer";
            tmpBankHeader.erpJnlNo = pReq1908.singleDetail.askNumber;
            tmpBankHeader.erpTrsTimestamp = Format.DateTimeFormat.format(pReq1908.singleDetail.getPayDateTime());
            //tmpBankHeader.erpTrsTimestamp = "2019-10-20" + tmpBankHeader.erpTrsTimestamp.substring(10);
            
            XmlTextWriter xmlWriter = new XmlTextWriter();
            writeCommonHead(xmlWriter, tmpBankHeader);

            XElement tmpXElement = new XElement("Body", "");
            tmpXElement.addChild(new XElement("PayerAcNo", pReq1908.singleDetail.payAct));
            tmpXElement.addChild(new XElement("PayeeAcNo", pReq1908.singleDetail.recAct));
            tmpXElement.addChild(new XElement("PayeeAcName", pReq1908.singleDetail.recName));
            tmpXElement.addChild(new XElement("TrsAmount", pReq1908.singleDetail.payAmount));
            tmpXElement.addChild(new XElement("PayerCurrency", convertCurToBank(pReq1908.singleDetail.recCur)));
            tmpXElement.addChild(new XElement("TrsPassword", ""));
            tmpXElement.addChild(new XElement("Remark", pReq1908.singleDetail.abstractATS));
            
            nodeAnalysis(pReq1908.singleDetail.srcXElement, tmpXElement, getCharset());
            
            xmlWriter.writeXElement(tmpXElement);
            xmlWriter.writeEndDocument();

            String[] tmpStrRet = sendToBank(xmlWriter.toXmlString(), "B2EBankInnerTransfer", false,"1");

            if (tmpStrRet[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    tmpRetDetail.respCode = "0";
                    tmpRetDetail.respInfo = tmpBkReader.getFirstText("/Message/Head/IBSReturnMsg");
                    
                    String tmpRespCode = tmpBkReader.getFirstText("/Message/Head/IBSReturnCode");
                    if ("000000".equals(tmpRespCode)) {
                        tmpRetDetail.transState = tmpBkReader.getFirstText("/Message/Body/ProcessState");
                        tmpRetDetail.payInfoCode = tmpBkReader.getFirstText("/Message/Body/ProcessState");
                    } else {
                        tmpRetDetail.transState = tmpRespCode;
                        tmpRetDetail.payInfoCode = tmpRetDetail.respInfo;
                    } 
                    tmpRetDetail.transAmt = Format.DecimalAmtFormat.format(Double.parseDouble(pReq1908.singleDetail.payAmount));
                } else {
                    tmpRetDetail.respCode = "-1";
                    tmpRetDetail.respInfo = tmpSbMsg.toString();
                }
            } else if (ConnState.FAIL.equals(tmpStrRet[0])) {
                tmpRetDetail.respCode = "0";
                tmpRetDetail.respInfo = tmpStrRet[1];
                tmpRetDetail.transState = PaymentState.FAIL_Payment;
                tmpRetDetail.payInfoCode = tmpStrRet[0];
            } else {
                tmpRetDetail.respCode = "-1";
                tmpRetDetail.respInfo = tmpStrRet[0].toString();
            }
        } catch (Exception ex) {
        	ex.printStackTrace();
			tmpRetDetail.respCode = "-1";
			tmpRetDetail.respInfo = ex.getMessage();
			WriteBankLogLn(ex);
        }
        
        retAts.writeRetDetail(tmpRetDetail);
        return retAts;
    }

    /**
     * 跨行单笔支付
     * 
     * @param pReq1908
     * @return
     * @throws Exception
     */
    public RetAtsSingle crossPay(ReqSingle pReq1908) throws Exception {
        RetAtsSingle retAts = new RetAtsSingle(pReq1908.reqHeader);
        RetAtsSglDetail tmpRetDetail = new RetAtsSglDetail();
        tmpRetDetail.reqSeqID = pReq1908.singleDetail.askNumber;
        
        try {
        	BOZZ02Header tmpBankHeader = new BOZZ02Header();
            tmpBankHeader.trsCode = "B2ECrossBankTransfer";
            tmpBankHeader.erpJnlNo = pReq1908.singleDetail.askNumber;
            tmpBankHeader.erpTrsTimestamp = Format.DateTimeFormat.format(pReq1908.singleDetail.getPayDateTime());
            //tmpBankHeader.erpTrsTimestamp = "2019-10-20" + tmpBankHeader.erpTrsTimestamp.substring(10);
            
            XmlTextWriter xmlWriter = new XmlTextWriter();
            writeCommonHead(xmlWriter, tmpBankHeader);

            XElement tmpXElement = new XElement("Body", "");
            tmpXElement.addChild(new XElement("PayerAcNo", pReq1908.singleDetail.payAct));
            tmpXElement.addChild(new XElement("PayeeAcNo", pReq1908.singleDetail.recAct));
            tmpXElement.addChild(new XElement("PayeeAcName", pReq1908.singleDetail.recName));
            tmpXElement.addChild(new XElement("PayeeBankCode", pReq1908.singleDetail.cnapsCode));
            tmpXElement.addChild(new XElement("TrsAmount", pReq1908.singleDetail.payAmount));
            tmpXElement.addChild(new XElement("PayerCurrency", convertCurToBank(pReq1908.singleDetail.recCur)));
            String priority = "1".equals(pReq1908.singleDetail.paySpd) ? "H" : "N";
            String urgentFlag = getBankConfig().getValueAsString("UrgentLargeAmount");
            if (StringHelper.hasAnyChar(urgentFlag)) {
                if ((new BigDecimal(pReq1908.singleDetail.payAmount)).compareTo(new BigDecimal(urgentFlag)) > 0) {
                    priority = "H";
                }
            }
            tmpXElement.addChild(new XElement("Priority", priority));
            tmpXElement.addChild(new XElement("TrsPassword", ""));
            tmpXElement.addChild(new XElement("Remark", pReq1908.singleDetail.abstractATS));
            
            nodeAnalysis(pReq1908.singleDetail.srcXElement, tmpXElement, getCharset());
            
            xmlWriter.writeXElement(tmpXElement);
            xmlWriter.writeEndDocument();

            String[] tmpStrRet = sendToBank(xmlWriter.toXmlString(), "B2ECrossBankTransfer", true,"1");

            if (tmpStrRet[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                if (tmpBkReader != null) {
                	tmpRetDetail.respCode = "0";
                    tmpRetDetail.respInfo = tmpBkReader.getFirstText("/Message/Head/IBSReturnMsg");
                    
                    String tmpRespCode = tmpBkReader.getFirstText("/Message/Head/IBSReturnCode");
                    if ("000000".equals(tmpRespCode)) {
                        tmpRetDetail.transState = tmpBkReader.getFirstText("/Message/Body/ProcessState");
                        tmpRetDetail.payInfoCode = tmpBkReader.getFirstText("/Message/Body/ProcessState");
                    } else {
                        tmpRetDetail.transState = tmpRespCode;
                        tmpRetDetail.payInfoCode = tmpRetDetail.respInfo;
                    } 
                    tmpRetDetail.transAmt = Format.DecimalAmtFormat.format(Double.parseDouble(pReq1908.singleDetail.payAmount));
                } else {
                    tmpRetDetail.respCode = "-1";
                    tmpRetDetail.respInfo = tmpSbMsg.toString();
                }
            } else if (tmpStrRet[0].equals(ConnState.FAIL)) {
                tmpRetDetail.respCode = "0";
                tmpRetDetail.respInfo = tmpStrRet[1];
                tmpRetDetail.reqSeqID = pReq1908.singleDetail.askNumber;
                tmpRetDetail.transState = PaymentState.FAIL_Payment;
                tmpRetDetail.payInfoCode = tmpStrRet[0];
            } else {
                tmpRetDetail.respCode = "-1";
                tmpRetDetail.respInfo = tmpStrRet[0].toString();
            }
	    } catch (Exception ex) {
	    	ex.printStackTrace();
			tmpRetDetail.respCode = "-1";
			tmpRetDetail.respInfo = ex.getMessage();
			WriteBankLogLn(ex);
	    }
        
        retAts.writeRetDetail(tmpRetDetail);
        return retAts;
    }

    @Override
    public RetAtsSingle d_1944_QrySglPay(ReqQrySingle p_req1944) throws Exception {
        RetAtsSingle retAts = new RetAtsSingle(p_req1944.reqHeader);
        RetAtsSglDetail tmpRetDetail = new RetAtsSglDetail();
        tmpRetDetail.reqSeqID = p_req1944.askNumber;
        
        try {
    		BOZZ02Header tmpBankHeader = new BOZZ02Header();
            tmpBankHeader.trsCode = "SingleTrsJnlsQryB2E";
            tmpBankHeader.erpJnlNo = getQryTransID();
            tmpBankHeader.erpTrsTimestamp = Format.DateTimeFormat.format(new Date());
            //tmpBankHeader.erpTrsTimestamp = "2019-10-20" + tmpBankHeader.erpTrsTimestamp.substring(10);
            
            XmlTextWriter xmlWriter = new XmlTextWriter();
            writeCommonHead(xmlWriter, tmpBankHeader);
            
            String tmpPaySendDate = Format.Date8Format.format(p_req1944.getBgnDateTime());
            //tmpPaySendDate = "20191020";
            
            xmlWriter.writeStartElement("Body");
            xmlWriter.writeElementString("TrsType", "1");
            xmlWriter.writeElementString("PayerAcNo", p_req1944.payAct);
            xmlWriter.writeElementString("BeginDate", tmpPaySendDate);
            xmlWriter.writeElementString("EndDate", tmpPaySendDate);
            xmlWriter.writeElementString("ErpJnlNo", p_req1944.reqHeader.reqSeqID);
            xmlWriter.writeElementString("PayeeAcNo", "");
            xmlWriter.writeElementString("PayeeAcName", "");
            xmlWriter.writeElementString("ProcessState", "");
            xmlWriter.writeElementString("BeginAmount", "");
            xmlWriter.writeElementString("EndAmount", "");
            xmlWriter.writeElementString("JnlNo", "");
            xmlWriter.writeElementString("BeginCount", "1");
            xmlWriter.writeElementString("QueryCount", "1");
            xmlWriter.writeEndDocument();

            String[] tmpStrRet = sendToBank(xmlWriter.toXmlString(), "SingleTrsJnlsQryB2E", true,"1");

            if (tmpStrRet[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                if (tmpBkReader != null) {
                	tmpRetDetail.respCode = "0";
                    tmpRetDetail.respInfo = tmpBkReader.getFirstText("/Message/Head/IBSReturnMsg");
                    
                    String bankRetCode = tmpBkReader.getFirstText("/Message/Head/IBSReturnCode");
                    if ("000000".equals(bankRetCode)) {
                        if (tmpBkReader.read("/Message/Body/List/Map")) {
                            tmpRetDetail.transState = tmpBkReader.readedXElement.getSingleText("ProcessState");
                            tmpRetDetail.payInfoCode = tmpBkReader.readedXElement.getSingleText("ProcessState");
                            tmpRetDetail.transAmt = Format.DecimalAmtFormat.format(Double.parseDouble(tmpBkReader.readedXElement.getSingleText("TrsAmount")));
                        } else {
                            if ("4".equals(p_req1944.payState)) {
                                p_req1944.payState = "5";
                            }
                            if (canBeNotExist(p_req1944, tmpRetDetail, 30)) {
                                tmpRetDetail.respCode = "0";
                                tmpRetDetail.respInfo = "记录不存在!";
                                tmpRetDetail.transState = "E1302";
                                tmpRetDetail.payInfoCode = "E1302";
                                retAts.writeRetDetail(tmpRetDetail);
                                return retAts;
                            }
                        }
                    } else {
                        tmpRetDetail.respCode = "-1";
                        tmpRetDetail.respInfo = tmpBkReader.getFirstText("/Message/Head/IBSReturnMsg");
                    }
                } else {
                    tmpRetDetail.respCode = "-1";
                    tmpRetDetail.respInfo = tmpSbMsg.toString();
                }
            } else {
                tmpRetDetail.respCode = "-1";
                tmpRetDetail.respInfo = tmpStrRet[0].toString();
            }
        } catch (Exception ex) {
			ex.printStackTrace();
			tmpRetDetail.respCode = "-1";
			tmpRetDetail.respInfo = ex.getMessage();
			WriteBankLogLn(ex);
		}
        
        retAts.writeRetDetail(tmpRetDetail);
        return retAts;
    }

    @Override
    public RetAtsSingleBat d_1908BAT_SglBatPay(ReqSingleBat p_req1908BAT) throws Exception {
        return null;
    }

    @Override
    public RetAtsSingleBat d_1944BAT_QrySglBatPay(ReqQrySingleBat p_req1944BAT) throws Exception {
        return null;
    }
}
